package dev.ece.suit.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import dev.ece.suit.ui.event.SelectableGroupListener;

public class SelectableGroup<T extends Selectable> {

	private boolean multiple;
	
	private Vector<T> selections = new Vector<T>();

	private Vector<SelectableGroupListener<T>> selectableGroupListeners = new Vector<SelectableGroupListener<T>>();
	
	private T selected;
	
	public synchronized void select(T selection) {
		if(selection.isSelected()) {
			return;
		}
		if(selections.contains(selection)) {
			T selected = this.selected;
			this.selected = selection;
			this.selected.selected();
			if(!this.isMultiple()) {
				if(selected != null && selected.isSelected()) {
					selected.unselect();
				}
			}
			triggerSelectableGroupListeners();
		}
	}
	
	protected void triggerSelectableGroupListeners() {
		for(SelectableGroupListener<T> listener: getSelectableGroupListeners()) {
			listener.onSelectionSelected(this, selected);
		}
	}
	
	public T selectPrevious() {
		return selectPrevious(false);
	}
	
	public T selectPrevious(boolean cycle) {
		int preIndex = getSelectedIndex() - 1;
		//循环
		if(cycle) {
			if(!getSelections().isEmpty() && preIndex < 0) {
				T selection = getSelections().lastElement();
				this.select(selection);
				return selection;
			}
		}
		if(preIndex > -1 && preIndex < getSelections().size()) {
			T selection = getSelections().get(preIndex);
			this.select(selection);
			return selection;
		}
		return null;
	}
	
	public T selectNext() {
		return selectNext(false);
	}
	
	public T selectNext(boolean cycle) {
		int nextIndex = getSelectedIndex() + 1;
		if(cycle) {
			if(!getSelections().isEmpty() && nextIndex >= getSelections().size()) {
				T selection = getSelections().firstElement();
				this.select(selection);
				return selection;
			}
		}
		if(nextIndex > -1 && nextIndex < this.selections.size()) {
			T selection = selections.get(nextIndex);
			this.select(selection);
			return selection;
		}
		return null;
	}
	
	public int getSelectedIndex() {
		return selected != null && selected.isSelected() ? selections.indexOf(selected) : -1;
	}
	
	public T singleSelected() {
		return selected != null && selected.isSelected() ? selected : null;
	}
	
	public List<T> listSelected() {
		List<T> result = new ArrayList<T>();
		for(T selecable: selections) {
			if(selecable.isSelected()) {
				result.add(selecable);
			}
		}
		return result;
	}
	
	public void addSelection(T selection) {
		selections.add(selection);
	}
	
	public void addSelectableGroupListener(SelectableGroupListener<T> selectableGroupListener) {
		if(!getSelectableGroupListeners().contains(selectableGroupListener)) {
			getSelectableGroupListeners().add(selectableGroupListener);
		}
	}
	
	public void removeSelectableGroupListener(SelectableGroupListener<T> selectableGroupListener) {
		getSelectableGroupListeners().remove(selectableGroupListener);
	}
	
	protected Vector<SelectableGroupListener<T>> getSelectableGroupListeners() {
		return selectableGroupListeners;
	}

	public void removeSelection(T selection) {
		selections.remove(selection);
		if(this.selected != null && this.selected.equals(selection)) {
			this.selected = null;
		}
	}
	
	public Vector<T> getSelections() {
		return selections;
	}

	public boolean isMultiple() {
		return multiple;
	}

	public void setMultiple(boolean multiple) {
		this.multiple = multiple;
	}
	
}
